package com.youlu.campus.service.commission;

import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.UserParticipateActivityInfo;
import com.youlu.campus.entity.commission.DistributorChannel;
import com.youlu.campus.entity.commission.DistributorChannelActivity;
import com.youlu.campus.entity.commission.DistributorChannelSharingCommissionDetail;
import com.youlu.campus.entity.commission.UserParticipateDistributorChannelInfo;
import com.youlu.campus.entity.commission.dto.UserParticipateChannelQueryDTO;
import com.youlu.campus.service.activity.ActivityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

@Slf4j
@Service
public class UserParticipateDistributorChannelInfoService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Resource(name = "masterMongoTemplate")
    private MongoTemplate masterMongoTemplate;

    @Lazy
    @Autowired
    private ActivityService activityService;

    @Autowired
    private DistributorChannelService distributorChannelService;

    @Lazy
    @Autowired
    private DistributorChannelActivityService distributorChannelActivityService;

    public void initUserDistributorChannel(){
        log.info("初始化渠道分销用户 start");
        Query query = new Query();
        List<UserParticipateDistributorChannelInfo> list = this.mongoTemplate.find(query, UserParticipateDistributorChannelInfo.class);
        if(CollectionUtils.isEmpty(list)){
            return;
        }
        list.stream().forEach(userDistributorChannel -> {
            Query queryUser = new Query();
            queryUser.addCriteria(Criteria.where("userId").is(userDistributorChannel.getUserId()));
            queryUser.addCriteria(Criteria.where("activityId").is(userDistributorChannel.getActivityId()));
            queryUser.addCriteria(Criteria.where("activityChannelId").exists(Boolean.FALSE));
            UserParticipateActivityInfo userParticipateActivityInfo = this.mongoTemplate.findOne(queryUser, UserParticipateActivityInfo.class);
            if(Objects.nonNull(userParticipateActivityInfo)){
                log.info("【渠道分销用户】userId:{},activityId:{}",userDistributorChannel.getUserId(),userDistributorChannel.getActivityId());
                Update update = new Update();
                update.set("activityChannelId",userDistributorChannel.getActivityChannelId());
                this.mongoTemplate.updateFirst(queryUser,update,UserParticipateActivityInfo.class);
                queryUser = new Query();
                queryUser.addCriteria(Criteria.where("id").is(userDistributorChannel.getId()));
                update = new Update();
                Double qaScore = userParticipateActivityInfo.getQaScore();
                if(qaScore.compareTo(0D)==1){
                    update.set("qaScore",qaScore);
                }
                Double provinceQaScore = userParticipateActivityInfo.getProvinceQaScore();
                if(provinceQaScore.compareTo(0D)==1){
                    update.set("provinceQaScore",provinceQaScore);
                }
                Double countryQaScore = userParticipateActivityInfo.getCountryQaScore();
                if(countryQaScore.compareTo(0D)==1){
                    update.set("countryQaScore",countryQaScore);
                }
                if(qaScore.compareTo(0D)==1||provinceQaScore.compareTo(0D)==1||countryQaScore.compareTo(0D)==1){
                    this.mongoTemplate.updateFirst(queryUser,update,UserParticipateDistributorChannelInfo.class);
                }
            }
        });



        log.info("初始化渠道分销用户 end");

    }


    public Page<UserParticipateDistributorChannelInfo> list(UserParticipateChannelQueryDTO dto){
        String activityId = dto.getActivityId();
        String mobile = dto.getMobile();
        String name = dto.getName();
        Integer pageNo = dto.getPageNo();
        Integer pageSize = dto.getPageSize();
        String channelId = dto.getChannelId();
        PageRequest pageRequest = PageRequest.of(pageNo - 1,pageSize);
        Query query = new Query();
        if(StringUtils.isNotBlank(activityId)){
            query.addCriteria(Criteria.where("activityId").is(activityId));
        }
        if(StringUtils.isNotBlank(mobile)){
            query.addCriteria(Criteria.where("mobile").is(mobile));
        }
        if(StringUtils.isNotBlank(name)){
            Pattern pattern = Pattern.compile("^.*" + name + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("name").regex(pattern));
        }
        if(dto.getDistributorChannelRole()){
            List<String> listDistributorChannel = distributorChannelService.findDistributorChannelByDistributorChannelUserId(dto.getDistributorChannelUserId());
            if(CollectionUtils.isEmpty(listDistributorChannel)){
                return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
            }
            if (StringUtils.isNotBlank(channelId)) {
                if (listDistributorChannel.contains(channelId)) {
                    query.addCriteria(Criteria.where("activityChannelId").is(channelId));
                }
            } else {
                query.addCriteria(Criteria.where("activityChannelId").in(listDistributorChannel));
            }
        } else {
            if (StringUtils.isNotBlank(channelId)) {
                query.addCriteria(Criteria.where("activityChannelId").is(channelId));
            }
        }
        if(StringUtils.isNotBlank(dto.getUniversityId())){
            query.addCriteria(Criteria.where("universityId").is(dto.getUniversityId()));
        }
        long count = this.mongoTemplate.count(query, UserParticipateDistributorChannelInfo.class);
        if(count ==0){
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> count);
        }
        Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        List<UserParticipateDistributorChannelInfo> list = this.mongoTemplate.find(query.with(pageRequest), UserParticipateDistributorChannelInfo.class);
        list.forEach(user -> {
            ActivityInfo activityInfo = activityService.findOne(user.getActivityId());
            if(Objects.nonNull(activityInfo)){
                user.setActivityName(activityInfo.getName());
            }
            DistributorChannel distributorChannel = distributorChannelService.findById(user.getActivityChannelId());
            if(Objects.nonNull(distributorChannel)){
                user.setActivityChannelName(distributorChannel.getChannelName());
            }
        });
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }


    public UserParticipateDistributorChannelInfo findByUserIdAndActivityIdAndChannelId(String userId,
                                                                                       String activityId,
                                                                                       String channelId){
        if(StringUtils.isAnyBlank(userId,activityId)){
            log.error("【渠道用户参与活动报名】参数未空 userId:{},activityId:{},channelId:{}",userId,activityId,channelId);
            return null;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        if(StringUtils.isNotBlank(channelId)){
            query.addCriteria(Criteria.where("activityChannelId").is(channelId));
        }
        return this.masterMongoTemplate.findOne(query,UserParticipateDistributorChannelInfo.class);

    }

    @Async
    public void save(UserParticipateDistributorChannelInfo updateDistributorChannelInfo) {
        DistributorChannelActivity distributorChannelActivity = distributorChannelActivityService.findByChannelIdAndActivityId(updateDistributorChannelInfo.getActivityChannelId(),updateDistributorChannelInfo.getActivityId());
        if (Objects.isNull(distributorChannelActivity)) {
            log.error("【渠道用户报名】当前用户活动不属于该渠道 activityChannelId:{},activityId:{}",
                    updateDistributorChannelInfo.getActivityChannelId(), updateDistributorChannelInfo.getActivityId());
            return;
        }
        Date now = new Date();
        Update update = new Update();
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(updateDistributorChannelInfo.getUserId()));
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getActivityId())) {
            query.addCriteria(Criteria.where("activityId").is(updateDistributorChannelInfo.getActivityId()));
        }
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getActivityChannelId())) {
            query.addCriteria(Criteria.where("activityChannelId").is(updateDistributorChannelInfo.getActivityChannelId()));
        }
        Double qaScore = 0D;
        Double provinceQaScore = 0D;
        Double countryQaScore = 0D;
        UserParticipateDistributorChannelInfo userParticipate = this.mongoTemplate.findOne(query,
                UserParticipateDistributorChannelInfo.class);
        if (Objects.isNull(userParticipate)) {
            update.set("createdTime", now);
            update.set("signUpTime", now);
        } else {
            qaScore = userParticipate.getQaScore();
            provinceQaScore = userParticipate.getProvinceQaScore();
            countryQaScore = userParticipate.getCountryQaScore();
        }
        update.set("updatedTime", now);
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getUniversityId())) {
            update.set("universityId", updateDistributorChannelInfo.getUniversityId());
        }
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getUniversityName())) {
            update.set("universityName", updateDistributorChannelInfo.getUniversityName());
        }
        if (Objects.nonNull(updateDistributorChannelInfo.getQaScore()) && updateDistributorChannelInfo.getQaScore() > 0 && updateDistributorChannelInfo.getQaScore().compareTo(qaScore) == 1) {
            update.set("qaScore", updateDistributorChannelInfo.getQaScore());
        }

        if (Objects.nonNull(updateDistributorChannelInfo.getCountryQaScore()) && updateDistributorChannelInfo.getCountryQaScore().intValue() > 0 && updateDistributorChannelInfo.getCountryQaScore().compareTo(countryQaScore) == 1) {
            update.set("countryQaScore", updateDistributorChannelInfo.getCountryQaScore());
        }
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getName())) {
            update.set("name", updateDistributorChannelInfo.getName());
        }
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getNickName())) {
            update.set("nickName", updateDistributorChannelInfo.getNickName());
        }
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getMobile())) {
            update.set("mobile", updateDistributorChannelInfo.getMobile());
        }
        if (Objects.nonNull(updateDistributorChannelInfo.getProvinceQaScore()) && updateDistributorChannelInfo.getProvinceQaScore() > 0 && updateDistributorChannelInfo.getProvinceQaScore().compareTo(provinceQaScore) == 1) {
            update.set("provinceQaScore", updateDistributorChannelInfo.getProvinceQaScore());
        }

        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getPlatform())) {
            update.set("platform", updateDistributorChannelInfo.getPlatform());
        }
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getOpenId())) {
            update.set("openId", updateDistributorChannelInfo.getOpenId());
        }
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getUnionId())) {
            update.set("unionId", updateDistributorChannelInfo.getUnionId());
        }
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getAppId())) {
            update.set("appId", updateDistributorChannelInfo.getAppId());
        }
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getChannelOwnerId())) {
            update.set("channelOwnerId", updateDistributorChannelInfo.getChannelOwnerId());
        }
        if (StringUtils.isNotBlank(updateDistributorChannelInfo.getChannelOwnerName())) {
            update.set("channelOwnerName", updateDistributorChannelInfo.getChannelOwnerName());
        }
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.returnNew(Boolean.TRUE);
        findAndModifyOptions.upsert(Boolean.TRUE);
        this.mongoTemplate.findAndModify(query, update, findAndModifyOptions,
                UserParticipateDistributorChannelInfo.class);
    }
}
